<script setup lang="ts">
import { calculateMasonryLayout, getResponsiveColumnCount } from '@/utils'
import type { ImageItem } from '@/utils'

// 模拟图片数据
const generateMockImages = (count: number): ImageItem[] => {
  return Array.from({ length: count }, (_, index) => {
    // 随机宽度和高度，确保不同的图片比例
    const width = 800 + Math.floor(Math.random() * 400)
    const height = 600 + Math.floor(Math.random() * 800)

    return {
      id: `image-${index + 1}`,
      url: `https://api.toserk.top/bing?random=${index + 1}`,
      width,
      height,
    }
  })
}

// 生成200张模拟图片
const allImages: ImageItem[] = generateMockImages(200)

// 响应式数据
const loadedImagesCount = ref(0) // 当前已加载的图片数量
const columns = ref<ReturnType<typeof calculateMasonryLayout>>([])
const containerWidth = ref(0)
const containerRef = ref<HTMLElement>()
const loading = ref(false) // 控制是否正在加载
const hasMore = ref(true) // 是否还有更多图片可以加载
const screenHeight = ref(window.innerHeight)
const pageSize = ref(0) // 每页加载的图片数量

// 计算列数和每列宽度
const columnCount = computed(() =>
  getResponsiveColumnCount(containerWidth.value - 30)
) // 减去间距
const columnWidth = computed(
  () =>
    (containerWidth.value - (columnCount.value - 1) * 10) / columnCount.value
) // 10px间距

// 当前要显示的图片
const displayImages = computed(() =>
  allImages.slice(0, loadedImagesCount.value)
)

// 计算屏幕能容纳的图片数量（包括屏幕一半高度的预加载）
const calculateVisibleImagesCount = () => {
  const estimatedImageHeight = 300 // 估算的平均图片高度
  const totalVisibleHeight = screenHeight.value * 1.5 // 可见区域 + 屏幕一半高度

  // 计算大致可见的图片数量
  // 列数 * (总可见高度 / 估算图片高度) * 1.5（为瀑布流布局增加一些缓冲）
  return Math.ceil(
    columnCount.value * (totalVisibleHeight / estimatedImageHeight) * 1.5
  )
}

// 加载更多图片
const loadMoreImages = () => {
  if (loading.value || !hasMore.value) return

  loading.value = true

  // 模拟网络延迟
  setTimeout(() => {
    const newCount = Math.min(
      loadedImagesCount.value + pageSize.value,
      allImages.length
    )
    loadedImagesCount.value = newCount

    // 如果已经加载了所有图片，设置hasMore为false
    if (loadedImagesCount.value >= allImages.length) {
      hasMore.value = false
    }

    loading.value = false
  }, 300)
}

// 检查是否需要加载更多（触底检测）
const checkScroll = () => {
  const scrollTop = window.scrollY
  const scrollHeight = document.documentElement.scrollHeight
  const clientHeight = document.documentElement.clientHeight

  // 当滚动到距离底部100px时触发加载
  if (scrollTop + clientHeight >= scrollHeight - 100) {
    loadMoreImages()
  }
}

// 更新瀑布流布局
const updateLayout = () => {
  columns.value = calculateMasonryLayout(
    displayImages.value,
    columnCount.value,
    columnWidth.value
  )
}

// 处理窗口大小变化
const handleResize = () => {
  if (containerRef.value) {
    containerWidth.value = containerRef.value.clientWidth
  }
  screenHeight.value = window.innerHeight

  // 重新计算页面大小
  const newPageSize = calculateVisibleImagesCount()
  if (newPageSize !== pageSize.value) {
    pageSize.value = newPageSize

    // 如果当前加载的图片数量少于新的页面大小，则加载更多
    if (loadedImagesCount.value < pageSize.value && hasMore.value) {
      loadedImagesCount.value = Math.min(pageSize.value, allImages.length)
      if (loadedImagesCount.value >= allImages.length) {
        hasMore.value = false
      }
    }
  }
}

// 监听窗口大小变化
onMounted(() => {
  if (containerRef.value) {
    containerWidth.value = containerRef.value.clientWidth
  }

  // 初始化屏幕高度和页面大小
  screenHeight.value = window.innerHeight
  pageSize.value = calculateVisibleImagesCount()

  // 初始加载第一页图片
  loadedImagesCount.value = Math.min(pageSize.value, allImages.length)
  if (loadedImagesCount.value >= allImages.length) {
    hasMore.value = false
  }

  updateLayout()

  // 添加事件监听
  window.addEventListener('resize', handleResize)
  window.addEventListener('scroll', checkScroll)

  // 监听计算属性变化
  watch([columnCount, columnWidth, displayImages], () => {
    updateLayout()
  })
})

onUnmounted(() => {
  // 移除事件监听
  window.removeEventListener('resize', handleResize)
  window.removeEventListener('scroll', checkScroll)
})
</script>

<template>
  <div class="flex flex-col min-h-screen">
    <div class="flex gap-[10px] w-full" ref="containerRef">
      <div
        v-for="(column, index) in columns"
        :key="index"
        class="flex flex-col gap-[10px]"
        :style="{ width: columnWidth + 'px' }"
      >
        <div
          v-for="item in column.items"
          :key="item.id"
          class="cursor-pointer rounded-lg overflow-hidden shadow-md hover:shadow-lg transition-shadow duration-300"
          :style="{ width: columnWidth + 'px' }"
        >
          <img
            :src="item.url"
            :style="{
              width: columnWidth + 'px',
              height: item.calculatedHeight + 'px',
              objectFit: 'cover',
            }"
            :alt="`Image ${item.id}`"
            loading="lazy"
            class="h-full object-cover transition-transform duration-300 hover:scale-110"
          />
        </div>
      </div>
    </div>

    <!-- 加载指示器 -->
    <div v-if="loading" class="flex justify-center items-center py-8">
      <div
        class="animate-spin rounded-full h-12 w-12 border-t-2 border-b-2 border-blue-500"
      ></div>
    </div>

    <!-- 无更多数据提示 -->
    <div v-else-if="!hasMore" class="text-center py-8 text-gray-500">
      没有更多图片了
    </div>
  </div>
</template>
